home *** CD-ROM | disk | FTP | other *** search
/ PC go! 2017 October / PCgo 10-2017 CD-ROM Germany.iso / nw.pak / Unnamed File 004914.txt < prev    next >
Encoding:
Text File  |  2015-07-29  |  6.9 KB  |  210 lines

  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4.  
  5. // This module implements the shared functionality for different guestview
  6. // containers, such as web_view, app_view, etc.
  7.  
  8. var DocumentNatives = requireNative('document_natives');
  9. var GuestView = require('guestView').GuestView;
  10. var IdGenerator = requireNative('id_generator');
  11.  
  12. function GuestViewContainer(element, viewType) {
  13.   privates(element).internal = this;
  14.   this.element = element;
  15.   this.elementAttached = false;
  16.   this.guest = new GuestView(viewType);
  17.   this.viewInstanceId = IdGenerator.GetNextId();
  18.   this.viewType = viewType;
  19.  
  20.   privates(this).browserPluginElement = this.createBrowserPluginElement();
  21.   this.setupFocusPropagation();
  22.  
  23.   var shadowRoot = this.element.createShadowRoot();
  24.   shadowRoot.appendChild(privates(this).browserPluginElement);
  25. }
  26.  
  27. // Forward public API methods from |proto| to their internal implementations.
  28. GuestViewContainer.forwardApiMethods = function(proto, apiMethods) {
  29.   var createProtoHandler = function(m) {
  30.     return function(var_args) {
  31.       var internal = privates(this).internal;
  32.       return $Function.apply(internal[m], internal, arguments);
  33.     };
  34.   };
  35.   for (var i = 0; apiMethods[i]; ++i) {
  36.     proto[apiMethods[i]] = createProtoHandler(apiMethods[i]);
  37.   }
  38. };
  39.  
  40. // Registers the browserplugin and guestview as custom elements once the
  41. // document has loaded.
  42. GuestViewContainer.registerElement =
  43.     function(guestViewContainerType) {
  44.   var useCapture = true;
  45.   window.addEventListener('readystatechange', function listener(event) {
  46.     if (document.readyState == 'loading') {
  47.       return;
  48.     }
  49.  
  50.     registerBrowserPluginElement(
  51.         guestViewContainerType.VIEW_TYPE.toLowerCase());
  52.     registerGuestViewElement(guestViewContainerType);
  53.     window.removeEventListener(event.type, listener, useCapture);
  54.   }, useCapture);
  55. };
  56.  
  57. GuestViewContainer.prototype.createBrowserPluginElement = function() {
  58.   // We create BrowserPlugin as a custom element in order to observe changes
  59.   // to attributes synchronously.
  60.   var browserPluginElement =
  61.       new GuestViewContainer[this.viewType + 'BrowserPlugin']();
  62.   privates(browserPluginElement).internal = this;
  63.   return browserPluginElement;
  64. };
  65.  
  66. GuestViewContainer.prototype.setupFocusPropagation = function() {
  67.   if (!this.element.hasAttribute('tabIndex')) {
  68.     // GuestViewContainer needs a tabIndex in order to be focusable.
  69.     // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute
  70.     // to allow GuestViewContainer to be focusable.
  71.     // See http://crbug.com/231664.
  72.     this.element.setAttribute('tabIndex', -1);
  73.   }
  74.   this.element.addEventListener('focus', function(e) {
  75.     // Focus the BrowserPlugin when the GuestViewContainer takes focus.
  76.     privates(this).browserPluginElement.focus();
  77.   }.bind(this));
  78.   this.element.addEventListener('blur', function(e) {
  79.     // Blur the BrowserPlugin when the GuestViewContainer loses focus.
  80.     privates(this).browserPluginElement.blur();
  81.   }.bind(this));
  82. };
  83.  
  84. GuestViewContainer.prototype.attachWindow = function() {
  85.   if (!this.internalInstanceId) {
  86.     return true;
  87.   }
  88.  
  89.   this.guest.attach(this.internalInstanceId,
  90.                     this.viewInstanceId,
  91.                     this.buildAttachParams());
  92.   return true;
  93. };
  94.  
  95. GuestViewContainer.prototype.handleBrowserPluginAttributeMutation =
  96.     function(name, oldValue, newValue) {
  97.   if (name == 'internalinstanceid' && !oldValue && !!newValue) {
  98.     privates(this).browserPluginElement.removeAttribute('internalinstanceid');
  99.     this.internalInstanceId = parseInt(newValue);
  100.  
  101.     if (!this.guest.getId()) {
  102.       return;
  103.     }
  104.     this.guest.attach(this.internalInstanceId,
  105.                       this.viewInstanceId,
  106.                       this.buildAttachParams());
  107.   }
  108. };
  109.  
  110. // Implemented by the specific view type, if needed.
  111. GuestViewContainer.prototype.buildAttachParams = function() { return {}; };
  112. GuestViewContainer.prototype.handleAttributeMutation = function() {};
  113. GuestViewContainer.prototype.onElementAttached = function() {};
  114. GuestViewContainer.prototype.onElementDetached = function() {
  115.   this.guest.destroy();
  116. };
  117.  
  118. // Registers the browser plugin <object> custom element. |viewType| is the
  119. // name of the specific guestview container (e.g. 'webview').
  120. function registerBrowserPluginElement(viewType) {
  121.   var proto = Object.create(HTMLObjectElement.prototype);
  122.  
  123.   proto.createdCallback = function() {
  124.     this.setAttribute('type', 'application/browser-plugin');
  125.     this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId());
  126.     this.style.width = '100%';
  127.     this.style.height = '100%';
  128.   };
  129.  
  130.   proto.attachedCallback = function() {
  131.     // Load the plugin immediately.
  132.     var unused = this.nonExistentAttribute;
  133.   };
  134.  
  135.   proto.attributeChangedCallback = function(name, oldValue, newValue) {
  136.     var internal = privates(this).internal;
  137.     if (!internal) {
  138.       return;
  139.     }
  140.     internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue);
  141.   };
  142.  
  143.   GuestViewContainer[viewType + 'BrowserPlugin'] =
  144.       DocumentNatives.RegisterElement(viewType + 'browserplugin',
  145.                                       {extends: 'object', prototype: proto});
  146.  
  147.   delete proto.createdCallback;
  148.   delete proto.attachedCallback;
  149.   delete proto.detachedCallback;
  150.   delete proto.attributeChangedCallback;
  151. };
  152.  
  153. // Registers the guestview container as a custom element.
  154. // |guestViewContainerType| is the type of guestview container
  155. // (e.g.WebViewImpl).
  156. function registerGuestViewElement(guestViewContainerType) {
  157.   var proto = Object.create(HTMLElement.prototype);
  158.  
  159.   proto.createdCallback = function() {
  160.     new guestViewContainerType(this);
  161.   };
  162.  
  163.   proto.attachedCallback = function() {
  164.     var internal = privates(this).internal;
  165.     if (!internal) {
  166.       return;
  167.     }
  168.     internal.elementAttached = true;
  169.     internal.onElementAttached();
  170.   };
  171.  
  172.   proto.attributeChangedCallback = function(name, oldValue, newValue) {
  173.     var internal = privates(this).internal;
  174.     if (!internal) {
  175.       return;
  176.     }
  177.     internal.handleAttributeMutation(name, oldValue, newValue);
  178.   };
  179.  
  180.   proto.detachedCallback = function() {
  181.     var internal = privates(this).internal;
  182.     if (!internal) {
  183.       return;
  184.     }
  185.     internal.elementAttached = false;
  186.     internal.onElementDetached();
  187.   };
  188.  
  189.   // Let the specific view type add extra functionality to its custom element
  190.   // through |proto|.
  191.   if (guestViewContainerType.setupElement) {
  192.     guestViewContainerType.setupElement(proto);
  193.   }
  194.  
  195.   window[guestViewContainerType.VIEW_TYPE] =
  196.       DocumentNatives.RegisterElement(
  197.           guestViewContainerType.VIEW_TYPE.toLowerCase(),
  198.           {prototype: proto});
  199.  
  200.   // Delete the callbacks so developers cannot call them and produce unexpected
  201.   // behavior.
  202.   delete proto.createdCallback;
  203.   delete proto.attachedCallback;
  204.   delete proto.detachedCallback;
  205.   delete proto.attributeChangedCallback;
  206. }
  207.  
  208. // Exports.
  209. exports.GuestViewContainer = GuestViewContainer;
  210.